{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": "# 7 层级索引（hierarchical indexing）分为多个层级（机器学习，深度学习不重要）也可以使用iloc和loc进行索引。"
  },
  {
   "cell_type": "code",
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "#MultiIndex是层级索引，索引类型的一种\n",
    "index1 = pd.MultiIndex.from_arrays([['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd'],\n",
    "                [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]], names=['cloth', 'size'])\n",
    "\n",
    "ser_obj = pd.Series(np.random.randn(12),index=index1)\n",
    "print(ser_obj)\n",
    "print(type(ser_obj)) #Series\n",
    "print(type(ser_obj.index)) #索引类型，MultiIndex\n",
    "print(ser_obj.index)\n",
    "print(ser_obj.index.levels) #层级索引的索引值\n",
    "ser_obj.index.codes  #没那么重要，代表索引的位置\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-01-07T13:45:48.559688Z",
     "start_time": "2025-01-07T13:45:48.550409Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cloth  size\n",
      "a      0       0.333049\n",
      "       1       1.026441\n",
      "       2       2.029567\n",
      "b      0      -0.566691\n",
      "       1      -0.470984\n",
      "       2      -0.016213\n",
      "c      0       0.241662\n",
      "       1      -0.390302\n",
      "       2      -0.946050\n",
      "d      0       0.709588\n",
      "       1      -0.601689\n",
      "       2      -1.004656\n",
      "dtype: float64\n",
      "<class 'pandas.core.series.Series'>\n",
      "<class 'pandas.core.indexes.multi.MultiIndex'>\n",
      "MultiIndex([('a', 0),\n",
      "            ('a', 1),\n",
      "            ('a', 2),\n",
      "            ('b', 0),\n",
      "            ('b', 1),\n",
      "            ('b', 2),\n",
      "            ('c', 0),\n",
      "            ('c', 1),\n",
      "            ('c', 2),\n",
      "            ('d', 0),\n",
      "            ('d', 1),\n",
      "            ('d', 2)],\n",
      "           names=['cloth', 'size'])\n",
      "[['a', 'b', 'c', 'd'], [0, 1, 2]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "FrozenList([[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 5
  },
  {
   "cell_type": "code",
   "source": [
    "ser_obj"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-01-07T13:44:34.530754Z",
     "start_time": "2025-01-07T13:44:34.526002Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "cloth  size\n",
       "a      0      -2.155176\n",
       "       1       0.154992\n",
       "       2       0.128606\n",
       "b      0      -1.165669\n",
       "       1      -0.910591\n",
       "       2       0.434421\n",
       "c      0       0.407120\n",
       "       1       0.810592\n",
       "       2      -0.548506\n",
       "d      0      -0.540588\n",
       "       1       1.782570\n",
       "       2      -0.087781\n",
       "dtype: float64"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "source": [
    "#层级索引如何取数据\n",
    "print('-'*50)\n",
    "print(ser_obj['c']) #取出c的所有数据，取出的是series\n",
    "print('-'*50)\n",
    "print(ser_obj.loc['a', 2])\n",
    "print('-'*50)\n",
    "print(ser_obj[:, 2]) #取出所有行的内层索引为2的数据"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-01-07T13:47:06.351566Z",
     "start_time": "2025-01-07T13:47:06.317121Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--------------------------------------------------\n",
      "size\n",
      "0    0.241662\n",
      "1   -0.390302\n",
      "2   -0.946050\n",
      "dtype: float64\n",
      "--------------------------------------------------\n",
      "2.0295666593281574\n",
      "--------------------------------------------------\n",
      "cloth\n",
      "a    2.029567\n",
      "b   -0.016213\n",
      "c   -0.946050\n",
      "d   -1.004656\n",
      "dtype: float64\n"
     ]
    },
    {
     "ename": "IndexingError",
     "evalue": "Too many indexers",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mIndexingError\u001B[0m                             Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[8], line 8\u001B[0m\n\u001B[0;32m      6\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m-\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;241m*\u001B[39m\u001B[38;5;241m50\u001B[39m)\n\u001B[0;32m      7\u001B[0m \u001B[38;5;28mprint\u001B[39m(ser_obj[:, \u001B[38;5;241m2\u001B[39m]) \u001B[38;5;66;03m#取出所有行的内层索引为2的数据\u001B[39;00m\n\u001B[1;32m----> 8\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[43mser_obj\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43miloc\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;241;43m3\u001B[39;49m\u001B[43m,\u001B[49m\u001B[38;5;241;43m2\u001B[39;49m\u001B[43m]\u001B[49m)\n",
      "File \u001B[1;32mE:\\python\\Lib\\site-packages\\pandas\\core\\indexing.py:1184\u001B[0m, in \u001B[0;36m_LocationIndexer.__getitem__\u001B[1;34m(self, key)\u001B[0m\n\u001B[0;32m   1182\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_is_scalar_access(key):\n\u001B[0;32m   1183\u001B[0m         \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mobj\u001B[38;5;241m.\u001B[39m_get_value(\u001B[38;5;241m*\u001B[39mkey, takeable\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_takeable)\n\u001B[1;32m-> 1184\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_getitem_tuple\u001B[49m\u001B[43m(\u001B[49m\u001B[43mkey\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m   1185\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m   1186\u001B[0m     \u001B[38;5;66;03m# we by definition only have the 0th axis\u001B[39;00m\n\u001B[0;32m   1187\u001B[0m     axis \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39maxis \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;241m0\u001B[39m\n",
      "File \u001B[1;32mE:\\python\\Lib\\site-packages\\pandas\\core\\indexing.py:1690\u001B[0m, in \u001B[0;36m_iLocIndexer._getitem_tuple\u001B[1;34m(self, tup)\u001B[0m\n\u001B[0;32m   1689\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m_getitem_tuple\u001B[39m(\u001B[38;5;28mself\u001B[39m, tup: \u001B[38;5;28mtuple\u001B[39m):\n\u001B[1;32m-> 1690\u001B[0m     tup \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_validate_tuple_indexer\u001B[49m\u001B[43m(\u001B[49m\u001B[43mtup\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m   1691\u001B[0m     \u001B[38;5;28;01mwith\u001B[39;00m suppress(IndexingError):\n\u001B[0;32m   1692\u001B[0m         \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_getitem_lowerdim(tup)\n",
      "File \u001B[1;32mE:\\python\\Lib\\site-packages\\pandas\\core\\indexing.py:962\u001B[0m, in \u001B[0;36m_LocationIndexer._validate_tuple_indexer\u001B[1;34m(self, key)\u001B[0m\n\u001B[0;32m    957\u001B[0m \u001B[38;5;129m@final\u001B[39m\n\u001B[0;32m    958\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m_validate_tuple_indexer\u001B[39m(\u001B[38;5;28mself\u001B[39m, key: \u001B[38;5;28mtuple\u001B[39m) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28mtuple\u001B[39m:\n\u001B[0;32m    959\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m    960\u001B[0m \u001B[38;5;124;03m    Check the key for valid keys across my indexer.\u001B[39;00m\n\u001B[0;32m    961\u001B[0m \u001B[38;5;124;03m    \"\"\"\u001B[39;00m\n\u001B[1;32m--> 962\u001B[0m     key \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_validate_key_length\u001B[49m\u001B[43m(\u001B[49m\u001B[43mkey\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    963\u001B[0m     key \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_expand_ellipsis(key)\n\u001B[0;32m    964\u001B[0m     \u001B[38;5;28;01mfor\u001B[39;00m i, k \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28menumerate\u001B[39m(key):\n",
      "File \u001B[1;32mE:\\python\\Lib\\site-packages\\pandas\\core\\indexing.py:1001\u001B[0m, in \u001B[0;36m_LocationIndexer._validate_key_length\u001B[1;34m(self, key)\u001B[0m\n\u001B[0;32m    999\u001B[0m             \u001B[38;5;28;01mraise\u001B[39;00m IndexingError(_one_ellipsis_message)\n\u001B[0;32m   1000\u001B[0m         \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_validate_key_length(key)\n\u001B[1;32m-> 1001\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m IndexingError(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mToo many indexers\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[0;32m   1002\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m key\n",
      "\u001B[1;31mIndexingError\u001B[0m: Too many indexers"
     ]
    }
   ],
   "execution_count": 8
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 交换层级"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "source": [
    "print(ser_obj.swaplevel())\n",
    "print('-'*50)\n",
    "print(ser_obj)\n",
    "print('-'*50)\n",
    "ser_obj=ser_obj.swaplevel()\n",
    "print(ser_obj)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-01-07T13:48:37.212104Z",
     "start_time": "2025-01-07T13:48:37.205123Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "size  cloth\n",
      "0     a        0.333049\n",
      "1     a        1.026441\n",
      "2     a        2.029567\n",
      "0     b       -0.566691\n",
      "1     b       -0.470984\n",
      "2     b       -0.016213\n",
      "0     c        0.241662\n",
      "1     c       -0.390302\n",
      "2     c       -0.946050\n",
      "0     d        0.709588\n",
      "1     d       -0.601689\n",
      "2     d       -1.004656\n",
      "dtype: float64\n",
      "--------------------------------------------------\n",
      "cloth  size\n",
      "a      0       0.333049\n",
      "       1       1.026441\n",
      "       2       2.029567\n",
      "b      0      -0.566691\n",
      "       1      -0.470984\n",
      "       2      -0.016213\n",
      "c      0       0.241662\n",
      "       1      -0.390302\n",
      "       2      -0.946050\n",
      "d      0       0.709588\n",
      "       1      -0.601689\n",
      "       2      -1.004656\n",
      "dtype: float64\n",
      "--------------------------------------------------\n",
      "size  cloth\n",
      "0     a        0.333049\n",
      "1     a        1.026441\n",
      "2     a        2.029567\n",
      "0     b       -0.566691\n",
      "1     b       -0.470984\n",
      "2     b       -0.016213\n",
      "0     c        0.241662\n",
      "1     c       -0.390302\n",
      "2     c       -0.946050\n",
      "0     d        0.709588\n",
      "1     d       -0.601689\n",
      "2     d       -1.004656\n",
      "dtype: float64\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "cell_type": "code",
   "source": [
    "print(ser_obj.sort_index(level=0))  #层级索引按那个索引级别排序,level=0表示按最外层索引排序"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-01-07T13:48:39.680153Z",
     "start_time": "2025-01-07T13:48:39.675097Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "size  cloth\n",
      "0     a        0.333049\n",
      "      b       -0.566691\n",
      "      c        0.241662\n",
      "      d        0.709588\n",
      "1     a        1.026441\n",
      "      b       -0.470984\n",
      "      c       -0.390302\n",
      "      d       -0.601689\n",
      "2     a        2.029567\n",
      "      b       -0.016213\n",
      "      c       -0.946050\n",
      "      d       -1.004656\n",
      "dtype: float64\n"
     ]
    }
   ],
   "execution_count": 14
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-07T13:48:45.083617Z",
     "start_time": "2025-01-07T13:48:45.077628Z"
    }
   },
   "cell_type": "code",
   "source": "ser_obj",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "size  cloth\n",
       "0     a        0.333049\n",
       "1     a        1.026441\n",
       "2     a        2.029567\n",
       "0     b       -0.566691\n",
       "1     b       -0.470984\n",
       "2     b       -0.016213\n",
       "0     c        0.241662\n",
       "1     c       -0.390302\n",
       "2     c       -0.946050\n",
       "0     d        0.709588\n",
       "1     d       -0.601689\n",
       "2     d       -1.004656\n",
       "dtype: float64"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 15
  },
  {
   "cell_type": "code",
   "source": [
    "#把最大索引变为列索引\n",
    "df_obj=ser_obj.unstack()  #unstack的level参数是索引层级\n",
    "print(df_obj)\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-01-07T13:48:48.326582Z",
     "start_time": "2025-01-07T13:48:48.319548Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cloth         a         b         c         d\n",
      "size                                         \n",
      "0      0.333049 -0.566691  0.241662  0.709588\n",
      "1      1.026441 -0.470984 -0.390302 -0.601689\n",
      "2      2.029567 -0.016213 -0.946050 -1.004656\n"
     ]
    }
   ],
   "execution_count": 16
  },
  {
   "cell_type": "code",
   "source": [
    "print(df_obj)\n",
    "#对df进行stack，就会把行，列索引进行堆叠，变为series\n",
    "#把列索引放入内层,只能放到内层\n",
    "print(df_obj.stack())  #stack变为series和unstack保持一致的\n",
    "# df_obj=df_obj.transpose()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2025-01-07T13:48:52.155425Z",
     "start_time": "2025-01-07T13:48:52.149593Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cloth         a         b         c         d\n",
      "size                                         \n",
      "0      0.333049 -0.566691  0.241662  0.709588\n",
      "1      1.026441 -0.470984 -0.390302 -0.601689\n",
      "2      2.029567 -0.016213 -0.946050 -1.004656\n",
      "size  cloth\n",
      "0     a        0.333049\n",
      "      b       -0.566691\n",
      "      c        0.241662\n",
      "      d        0.709588\n",
      "1     a        1.026441\n",
      "      b       -0.470984\n",
      "      c       -0.390302\n",
      "      d       -0.601689\n",
      "2     a        2.029567\n",
      "      b       -0.016213\n",
      "      c       -0.946050\n",
      "      d       -1.004656\n",
      "dtype: float64\n"
     ]
    }
   ],
   "execution_count": 17
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
